/*******************************************************************************
 * Copyright (c) 2011 Olexandr V. Shaposhnikov.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Olexandr V. Shaposhnikov - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.funkyroach.msvctch.msvc2008;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector3;
import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
import org.eclipse.cdt.make.internal.core.scannerconfig2.PerProjectSICollector;
import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;

public class MSVC2008ScannerInfoCollector extends PerProjectSICollector implements IScannerInfoCollector3, IManagedScannerInfoCollector {
	protected Map<String, String> definedSymbols;
	protected static final String EQUALS = "=";	//$NON-NLS-1$
	protected List<String> includePaths;
	protected IProject project;
	
	public MSVC2008ScannerInfoCollector() {
		super();
		getDefinedSymbols().put("WIN32", "");
		
		//IPreferenceStore store = MSVCPlugin.getDefault().getPreferenceStore();
		
		getIncludePaths().clear();
		getIncludePaths().add( MSVC2008PathResolver.getMsvcHome() + "\\include" );
		
	}

	@SuppressWarnings("unchecked")
	public void contributeToScannerConfig(Object resource, Map scannerInfo) {
		// check the resource
		if (resource != null && resource instanceof IResource &&
				((IResource) resource).getProject() == project ) {
			List includes = (List) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS);
			List symbols = (List) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS);
			
			// This method will be called by the parser each time there is a new value
			Iterator pathIter = includes.listIterator();
			while (pathIter.hasNext()) {
				String path = (String) pathIter.next();
				getIncludePaths().add(path);
			}
			
			// Now add the macros
			Iterator symbolIter = symbols.listIterator();
			while (symbolIter.hasNext()) {
				// See if it has an equals
				String[] macroTokens = ((String)symbolIter.next()).split(EQUALS);
				String macro = macroTokens[0].trim();
				String value = (macroTokens.length > 1) ? macroTokens[1].trim() : new String();
				getDefinedSymbols().put(macro, value);
			}
		}
	}

	public Map<String, String> getDefinedSymbols() {
		if (definedSymbols == null) {
			definedSymbols = new HashMap<String, String>();
		}
		return definedSymbols;
	}
	
	public List<String> getIncludePaths() {
		if (includePaths == null) {
			includePaths = new ArrayList<String>();
		}
		return includePaths;
	}

	public void setProject(IProject project) {
		this.project = project;
	}

	@SuppressWarnings("unchecked")
	public List<String> getCollectedScannerInfo(Object resource, ScannerInfoTypes type) {
        List<String> rv = null;
        String errorMessage = null;
        if (resource == null) {
            errorMessage = "resource is null";//$NON-NLS-1$
        } 
        else if (!(resource instanceof IResource)) {
            errorMessage = "resource is not an IResource";//$NON-NLS-1$
        }
        else if (((IResource) resource).getProject() == null) {
            errorMessage = "project is null";//$NON-NLS-1$
        }
        else if (((IResource) resource).getProject() != project) {
            errorMessage = "wrong project";//$NON-NLS-1$
        }
        
        if (errorMessage != null) {
            TraceUtil.outputError("MSVC2008ScannerInfoCollector: ", errorMessage); //$NON-NLS-1$
        }
        else if (type.equals(ScannerInfoTypes.INCLUDE_PATHS)) {
            rv = getIncludePaths();
        }
        else if (type.equals(ScannerInfoTypes.SYMBOL_DEFINITIONS)) {
            rv = new ArrayList();
            Map symbols = getDefinedSymbols();
            for (Iterator i = symbols.keySet().iterator(); i.hasNext(); ) {
                String macro = (String) i.next();
                String value = (String) symbols.get(macro);
                if (value.length() > 0) {
                    rv.add(macro + EQUALS + value);
                }
                else {
                    rv.add(macro);
                }
            }
        }
        else {
            rv = new ArrayList();
        }
        return rv;
    }

}
